//
//  HttpClientForPHPSession.m
//  Moko
//
//  Created by cj848 on 11. 7. 23..
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "HttpClientForPHPSession.h"
#import "MokoAppDelegate.h"
#import "Reachability.h"

#define USER_AGENT [NSString stringWithFormat:@"Mozilla/5.0 (%@; U; CPU %@_%@ like Mac OS X; ko-kr)SeekoApp/%@", \
[[UIDevice currentDevice] model],\
[[UIDevice currentDevice] systemName],\
[[UIDevice currentDevice] systemVersion],\
[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey]\
]\

@implementation HttpClientForPHPSession
@synthesize _connection, _data, charset, _cookies;
@synthesize isLogin;
-(BOOL)requestURL:(NSString*)url httpMethod:(NSString*)method bodyData:(NSData*)bodyData isMultiPart:(BOOL)isMultipart boundary:(NSString*)boundary target:(id)tar selector:(SEL)sel {
    GET_APPDELEGATE;
    NSURL *URL = [NSURL URLWithString: [url stringByAddingPercentEscapesUsingEncoding:charset]];
	// Make a request (By default this is a GET request with no body).  It is mutable as we need to
	// Add the cookies to the request.
	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
    
	// If we have cookies, iterate though them and add them to the request.
	if (self._cookies) {
		NSEnumerator *enumerator = [self._cookies objectEnumerator];
		id cookie;
        cookie = [enumerator nextObject];
        
		while (cookie != nil) {
			[request addValue:[cookie value] forHTTPHeaderField:@"Cookies"];
            cookie = [enumerator nextObject];
		}
	}
    [request addValue:USER_AGENT forHTTPHeaderField:@"User-Agent"];
    // 글쓰기 및 기타 권한이 필요한 모든 곳에 레퍼러가 없으면 실행 안됨
    [request addValue:delegate.configVO.siteHostAddress forHTTPHeaderField:@"Referer"];
    if( isMultipart ) {
        // boundary는 멀티파트 전송시에 사용되며 시작과 끝에 존재하는 유니크한 문자열이다.
        [request addValue: [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];
    } else {
        [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    }
    [request setHTTPMethod:method];
    
    if( bodyData ) {
        
        [request setValue:[NSString stringWithFormat:@"%d",
                           [bodyData length]] forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody:bodyData];
    }
    // 타겟과 셀렉터를 지정
    target = tar;
    selector = sel;
         
    // Make the connection.  The connection will start immediately.  The connection is
    // asynchronous and the data will be returned via the delegate methods.  nil will be 
    // returned on error.
    // 네트워크가 사용중일때 스테이터스 바에서 보여줌
    
    
    
    [delegate.loadingAlertView show];
    CGPoint point = CGPointMake(delegate.loadingAlertView.bounds.size.width / 2, delegate.loadingAlertView.bounds.size.height - 50);
    if( point.x == 0 ) {
        point.x = 142;
        point.y = 91;
    }
    delegate.indicator.center = point;
    [delegate.indicator startAnimating];
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    if (_connection) {
        return YES;
    }
    else return NO;
}
-(id)init {
    self = [super init];
    // 기본 캐릭터셋은 euc-kr
    charset = 0x80000000 + kCFStringEncodingDOSKorean;
    // 최초에는 로그인이 되어있지 않은 상태
    isLogin = NO;
    _data = [[NSMutableData alloc] init];
    return self;
}
-(void)dealloc {
    [_data release];
    [_connection release];
    [_cookies release];
    [super dealloc];
}
-(void)setTarget:(id)t setSelector:(SEL)sel {
    target = t;
    selector = sel;
}
-(BOOL) didLogin {
    return isLogin;
}

// Delegate method called if an error occurred during the connection.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
	// We got an error.  Just for this example log it.
    GET_APPDELEGATE;
    [delegate.loadingAlertView dismissWithClickedButtonIndex:0 animated:YES];
	UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"네트워크 상태가 좋지 않습니다." message:@"네트워크 상태를 확인하세요." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"확인", nil];
    [alertView show];
    [alertView release];
	// Then tidy up
	[_connection release];
	[_data setLength:0];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
-(void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
    GET_APPDELEGATE;
    int nResult = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus];
    delegate.configTableController.totalBytesOfDataUsage += bytesWritten;
    switch (nResult) {
        case ReachableViaWiFi:
            delegate.configTableController.totalWifiBytesOfDataUsage += bytesWritten;
            break;
        case ReachableViaWWAN:
            delegate.configTableController.total3GBytesOfDataUsage += bytesWritten;
            break;
    }

}

// Delegate method called when a response has been received from the server.  All of the headers
// will have been received but not the body data yet.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
	// We're doing HTTP so we will have gotten a NSHTTPURLResponse!
	NSHTTPURLResponse* httpResponse = [(NSHTTPURLResponse*)response retain];
    
	// Check the status code and respond appropriately.
	switch ([httpResponse statusCode]) {
		case 200: {
			// Got a response so extract any cookies.  The array will be empty if there are none.
			NSDictionary *theHeaders = [httpResponse allHeaderFields];
			NSArray      *theCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:theHeaders forURL:[response URL]];
            
			// Save any cookies
			self._cookies = theCookies;			
            
		    break;
		}
            
		default:
			break;
	}
    
	// Initialised the received data which will contain the body of the response and will be
	// populated via the connection:didReceiveData call below.
    [httpResponse release];
}

// Delegate method called when body data has been received.  This will be called one or more times.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
	// Append the data received to our data
    [_data appendData:data];
	
}
// 기본적으로 오버라이드 돼야 할 메소드
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // 기본적으로 커넥션과 데이터를 릴리즈 해야된다.
    GET_APPDELEGATE;
    // 로딩뷰 제거
    [delegate.loadingAlertView dismissWithClickedButtonIndex:0 animated:YES];
    int nResult = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus];
    int data_length = [_data length];
    delegate.configTableController.totalBytesOfDataUsage += data_length;
    switch (nResult) {
        case ReachableViaWiFi:
            delegate.configTableController.totalWifiBytesOfDataUsage += data_length;
            break;
        case ReachableViaWWAN:
            delegate.configTableController.total3GBytesOfDataUsage += data_length;
            break;
    }
    [target performSelector:selector withObject:_data];
    [connection release];
    [_data setLength:0];
    [delegate.configTableController.tableView reloadData];
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

@end
